﻿using System;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Soundteller.Phone.Facade.Interfaces;
using Soundteller.Phone.Facade;
using System.Windows.Input;
using Microsoft.Xna.Framework.Input.Touch;

namespace Soundteller.Phone.Components
{
    public class SoundtellerComponent : Components.IGameComponent, Components.IDrawableGameComponent
    {
        private IAudioVisualFacade _audioVisualFacade;
        private IVisualFacade _visualFacade;
        private SpriteBatch _spriteBatch;

        private readonly object _lock = new object();
        private bool _ignoreMouse;

        public SoundtellerComponent(IVisualFacade visualFacade, IAudioVisualFacade audioVisualFacade)
        {
            if (visualFacade == null) throw new ArgumentNullException("visualFacade");
            if (audioVisualFacade == null) throw new ArgumentNullException("audioVisualFacade");

            _visualFacade = visualFacade;
            _audioVisualFacade = audioVisualFacade;
        }

        public void Initialize()
        {
            Debug.WriteLine("{0}.Initialize()", GetType().Namespace, null);

            _audioVisualFacade.SubscribePadStateUpdater();
            _audioVisualFacade.SubscribePadStateResetter();
        }

        public void LoadContent()
        {
            Debug.WriteLine("{0}.LoadContent()", GetType().Namespace, null);

            _spriteBatch = new SpriteBatch(GraphicsContext.GraphicsDevice);

            _audioVisualFacade.InitializeSoundteller(GraphicsContext.WindowWidth, GraphicsContext.WindowHeight);
        }

        public void Update(GameTime gameTime)
        {
            HandleTouch();

            _audioVisualFacade.UpdateSoundteller();
        }

        public void Draw(GameTime gameTime)
        {
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

            while (_visualFacade.PeekGraphicBuffer() != null)
            {
                var graphic = _visualFacade.PopGraphicBuffer();
                _spriteBatch.Draw(graphic.Texture, graphic.ScreenCoordinates, graphic.SpriteTint);
            }

            _spriteBatch.End();
        }

        private void HandleTouch()
        {
            lock (_lock)
            {
                foreach (var touch in TouchPanel.GetState())
                {
                    switch (touch.State)
                    {
                        case TouchLocationState.Pressed:
                            if (_ignoreMouse) return;

                             _ignoreMouse = true;
                            _audioVisualFacade.TouchPad(touch);
                            break;

                        case TouchLocationState.Released:
                            _ignoreMouse = false;
                            break;
                    }
                }
            }
        }
    }
}
